/**
 * In order to manage scopes, the VSL symbol table is implemented as a stack
 * of HashTables, a class implementing a map type data structure.
 *
 * Every insertion of a pair (key, value) is done in the table which is on top of stack
 *
 * Lookup method proceeds first with the top of stack and if nothing is found there
 * goes down in the stack. It ends the search at the first occurence of the key or 
 * when it reaches the bottom of the stack.
 *
 * The size attribute is a derived one which is there for avoiding numerous computations.
 *
 * This attribute is updated by the EnterScope and LeaveScope methods.  
 * 
 * @author MLB
 *
 */

public class SymbolTable{
    private SymbolTableElem current_table;
    private int scope_level;
    private int size;
	 
    /**
     * create a new symbol table. The current scope is zero.
     *
     */
    public SymbolTable(){
		  size = 1024;
		  current_table = new SymbolTableElem(null,size);
		  scope_level = 0;
    }
	/**
	 * Push a new hashtable which becomes the current one. Update the current
    * scope accordingly
	 */ 
    public void Enter_Scope(){
		  SymbolTableElem t = new SymbolTableElem(current_table,size);
		  current_table = t;
		  scope_level++;
    }
	 /**
	  * Pop the current hastable and decrement the current scope.
	  *
	  */
    public void Leave_Scope(){
		  current_table = current_table.englobante;
		  scope_level--;
    }
	 /**
	  * Lookup for a value associated with a key. Returns null if the key is not
	  * found. 
	  * @param name  string - the key
	  * @return Value with  Operand3a type (which might be necessary to cast)
	  */
    public Operand3a Lookup(String name){
		  return current_table.lookup(name);
    }
	 /**
	  * Put a pair (key, value) in the current table
	  * @param name : name (String)
	  * @param t : value of  Operand3a type
	  */
    public void Insert(String name, Operand3a t){
		   current_table.Insert(name,t);
    }
	 
	 /**
	  * Same as lookup. Kept here for historical reasons
	  */
	 public Operand3a get(String name){
		  return current_table.lookup(name);
	 }
	 /**
	  * Returns the current scope. 
	  */
    public int getScope(){
		  return scope_level;
    }
	 /**
	  * For debug ... display the name of the key associated with 
	  * whatever the user wants to display by mean of a <b>toString</b> method on 
	  * the object associated with the key.
	  */
    public void Affiche(){
		  System.out.println("\n ======= Symbol table ==========\n");
		  current_table.Affiche();
		  System.out.println("\n ======= End symbol table ==========\n");
    }

}
